package org.jdsm.gae.komarichyn.profile;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.lang.StringUtils;
import org.jdsm.flow.core.users.IGroup;
import org.jdsm.flow.core.users.IRole;
import org.jdsm.flow.core.users.IUser;
import org.jdsm.flow.core.users.IUserService;
import org.jdsm.flow.extensions.profile.IProfile;
import org.jdsm.flow.extensions.profile.IProfileService;
import org.jdsm.gae.komarichyn.ElementByBeanName;

import javax.annotation.Resource;
import java.util.*;

/**
 * User: mikom
 * Date: 11/29/12
 * Time: 5:59 PM
 */
public class ProfileAction extends ActionSupport {
    @Resource
    private IProfileService profileService;
    @Resource
    private IUserService userService;
    @Resource
    private IUser user;
    @Resource
    private IGroup group;
    @Resource
    private IRole role;
    @Resource
    private IProfile profile;

    private static final String __USER_KEY = "_USER_KEY";

    private List<IUser> users = new ArrayList<IUser>();
    @ElementByBeanName(value = "role")
    private List<IRole> roles = new ArrayList<IRole>();
    @ElementByBeanName(value = "group")
    private List<IGroup> groups = new ArrayList<IGroup>();

    /**
     * execution logging
     *
     * @return forward to result
     */
    public String signIn() {


        if (StringUtils.isEmpty(user.getNickName())) {
            addFieldError("user.nickName", "err.user.nickName.cant.be.empty");
            return INPUT;
        }
        IUser u = userService.findUserByNickName(user.getNickName());

        if (u == null) {
            addActionError("err.user.cant.find.user");
            return INPUT;
        }

        if (!StringUtils.equals(u.getPassword(), user.getPassword())) {
            addActionError("err.user.cant.find.user");
            return INPUT;
        }

        Map<String, Object> session = ActionContext.getContext().getSession();
        session.put(__USER_KEY, u);

        return SUCCESS;
    }

    /**
     * log out from system
     *
     * @return forward to result
     */
    public String signOut() {
        Map<String, Object> session = ActionContext.getContext().getSession();
        session.remove(__USER_KEY);
        return SUCCESS;
    }

    @Override
    public String execute() throws Exception {
//        userService.loadUser(user);
        return SUCCESS;
    }

    public String reassignGroups() throws Exception{
        userService.reassignUserGroups(user, new HashSet<IGroup>(groups));
        return SUCCESS;
    }

    public String reassignRoles() throws Exception{
        userService.reassignUserRoles(user, new HashSet<IRole>(roles));
        return SUCCESS;
    }

    public String loadUserInformation() throws Exception {
        this.user = userService.loadUser(user);
        roles = new ArrayList<IRole>(userService.findUserRoles(user));
        groups = new ArrayList<IGroup>(userService.findUserGroups(user));
        return SUCCESS;
    }

    public String loadUserGroups() throws Exception {
        userService.loadUser(user);
        groups = new ArrayList<IGroup>(userService.findUserGroups(user));
        return SUCCESS;
    }

    public String loadUserRoles() throws Exception {
        userService.loadUser(user);
        roles = new ArrayList<IRole>(userService.findUserRoles(user));
        return SUCCESS;
    }

    public String loadRole(){
        this.role = userService.loadRole(role);
        return SUCCESS;
    }

    public String loadGroup(){
        this.group = userService.loadGroup(group);
        return SUCCESS;
    }

    public String loadRoles(){
        roles = new ArrayList<IRole>(userService.loadRolesByCriteria(10, 0, true, "name"));
        return SUCCESS;
    }

    public String loadGroups(){
        groups = new ArrayList<IGroup>(userService.loadGroupsByCriteria(10, 0, true, "name"));
        return SUCCESS;
    }

    public String updateRole(){
        userService.saveOrUpdate(role);
        return SUCCESS;
    }

    public String updateGroup(){
        userService.saveOrUpdate(group);
        return SUCCESS;
    }

    public String removeRole(){
        userService.removeRole(role);
        return SUCCESS;
    }

    public String removeGroup(){
        userService.removeGroup(group);
        return SUCCESS;
    }

    /**
     * execution registration new user
     *
     * @return forward to result
     */
    public String signUp() {

        if (StringUtils.isEmpty(user.getNickName())) {
            addFieldError("user.nickName", "err.user.nickName.cant.be.empty");
            return INPUT;
        }
        IUser u = userService.findUserByNickName(user.getNickName());
        if (u != null) {
            addActionError("err.user.with.nickName.exist");
            return INPUT;
        }

        IRole role = userService.findRoleByName("USER");
        if (role == null) {
            role = userService.newRoleInstance("USER", 1000l);
            userService.saveOrUpdate(role);
        }

        IGroup group = userService.findGroupByName("USER");
        if (group == null) {
            group = userService.newGroupInstance("USER", 1000l);
            userService.saveOrUpdate(group);
        }

        userService.saveOrUpdate(user);

        userService.includeUser(user, role);
        userService.includeUser(user, group);

        return SUCCESS;
    }

    public String listUsers() throws Exception {
        Date date = new Date();
        this.users.clear();
        this.users.addAll(userService.loadUsersByCriteria(20, 0, true, "id"));
        return SUCCESS;
    }

    public String saveRole() throws Exception {
        userService.saveOrUpdate(role);
        return SUCCESS;
    }

    public String saveGroup() throws Exception {
        userService.saveOrUpdate(group);
        return SUCCESS;
    }

    public List<IGroup> getAllGroups() {
        return new ArrayList<IGroup>(userService.loadGroupsByCriteria(10, 0, true, "name"));
    }

    public List<IRole> getAllRoles() {
        return new ArrayList<IRole>(userService.loadRolesByCriteria(10, 0, true, "name"));
    }


    public IUser getUser() {
        return user;
    }

    public void setUser(IUser user) {
        this.user = user;
    }

    public IProfile getProfile() {
        return profile;
    }

    public void setProfile(IProfile profile) {
        this.profile = profile;
    }


    public List<IUser> getUsers() {
        return users;
    }

    public void setUsers(List<IUser> users) {
        this.users = users;
    }

    public List<IRole> getRoles() {
        return roles;
    }

    public void setRoles(List<IRole> roles) {
        this.roles = roles;
    }

    public List<IGroup> getGroups() {
        return groups;
    }

    public void setGroups(List<IGroup> groups) {
        this.groups = groups;
    }

    public IGroup getGroup() {
        return group;
    }

    public void setGroup(IGroup group) {
        this.group = group;
    }

    public IRole getRole() {
        return role;
    }

    public void setRole(IRole role) {
        this.role = role;
    }
}
